package edu.uow.scsse.main;

import java.io.File;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;

import edu.uow.scsse.gui.ResultDisplayWindow;
import edu.uow.scsse.gui.SpecifyProjectWindow;
import edu.uow.scsse.main.metrics.DesignMetricsCalculation;
import edu.uow.scsse.main.transformation.Transformation;

/**
 * Design Metrics driver
 * @author Tiancheng Zhang
 *
 */
public class DriverMain {
	
	/**Project Name*/
	private String projectName;
	/**File list*/
	private List<String> fileLists;
	/**result */
	private Map<String, Double> result;
	/**decimal format*/
	private final DecimalFormat twoDForm = new DecimalFormat("#.####");
	
	/**default trigging event weight*/
	private boolean defaultTriggingEventWeight;
	
	/**Trigging alternative plan weight*/
	private double trAltWeight;
	
	/**Result Display Window*/
	private ResultDisplayWindow resultDisplayWindow;
	
	
	/**
	 * Driver Main Constructor
	 */
	public DriverMain(String projectName, boolean defaultTriggingEventWeight, double trAltWeight)
	{
		this.projectName = projectName;
		this.defaultTriggingEventWeight = defaultTriggingEventWeight;
		this.trAltWeight = trAltWeight;
		this.fileLists = new ArrayList<String>();
		this.result = new HashMap<String, Double>();
		
	}
	
	/**
	 * start to run
	 */
	public void run()
	{
		this.fileLists.clear();
		if(findAllASLFiles()==null)
			return;
		
		this.resultDisplayWindow = new ResultDisplayWindow(projectName, this.defaultTriggingEventWeight, this.trAltWeight);
		
		for(String eachFilePath: fileLists)
		{
			String agentName = "";
			agentName = eachFilePath.substring(eachFilePath.lastIndexOf('\\')+1).split("\\.")[0];
			String r[] = new String[]{agentName, String.valueOf(result.get(eachFilePath))};
			resultDisplayWindow.getTableModelResult().addRow(r);
		}
		
		resultDisplayWindow.setVisible(true);

	}
	
	
	
	//find All asl files
	private String findAllASLFiles()
	{
		String projectLocation = getProjectPath();
		if(projectLocation == null)
		{
			return null;
		}
		refreshFileList(projectLocation);
		
		for(int i = 0; i < fileLists.size(); i++)
		{
			Transformation t = new Transformation(fileLists.get(i));
			try {
				DesignMetricsCalculation dmc= new DesignMetricsCalculation(t.generate());
				
				String filePath = fileLists.get(i);
				String agentName = fileLists.get(i).substring(fileLists.get(i).lastIndexOf('\\')+1).split("\\.")[0];
				result.put(filePath, Double.valueOf(twoDForm.format(dmc.reactivnessCalculation(this.defaultTriggingEventWeight,this.trAltWeight, agentName))));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return projectLocation;
		
	}
	
	/**
	 * get all asl files
	 * @param strPath
	 */
	private void refreshFileList(String strPath) { 
        File dir = new File(strPath); 
        File[] files = dir.listFiles(); 
        
        if (files == null) 
            return; 
        for (int i = 0; i < files.length; i++) { 
            if (files[i].isDirectory()) { 
                refreshFileList(files[i].getAbsolutePath()); 
            } else { 
//                String strFileName = files[i].getAbsolutePath().toLowerCase();
            	String filePath = files[i].getPath();
            	if(filePath.endsWith('.'+"asl") && !filePath.contains('\\'+"bin"+'\\'))
            	{
            		fileLists.add(files[i].getAbsolutePath()); 
            	}
            } 
        }
	}

	
	/**
	 * project path
	 * @return project path
	 */
	private String getProjectPath()
	{
		IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
		IProject project = workspaceRoot.getProject(this.projectName);
		if(!project.exists())
		{
			java.awt.EventQueue.invokeLater(new Runnable() {
	            public void run() {
	                new SpecifyProjectWindow("MAS project: " + projectName + " does not exist.").setVisible(true);
	            }
	        });
			return null;
		}
		
		if(!project.isOpen())
		{
				try {
					project.open(null);
				} catch (CoreException e) {
					e.printStackTrace();
				}
		}
		
		String locationString = project.getLocation().toString();
		return locationString;
	}
	
}
